# -*- tcl -*-
# # ## ### ##### ######## ############# #####################
##
# Test suite for Tcl/Hwloc binding.
# Topology API

# # ## ### ##### ######## ############# #####################
## Requirements

package require Tcl 8.5

if {[catch {package require tcltest 2}]} {
    puts stderr "Skipping tests in [info script].  tcltest 2 required."
    return
}

# # ## ### ##### ######## ############# #####################

test hwloc-topology-1.0 {wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X option ?arg? ..."}

test hwloc-topology-1.1 {bad method} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X bogus
} -cleanup {
    X destroy
} -returnCodes error \
    -result {bad option "bogus": must be convert, cpubind, cpuset, depth, destroy, element, element_by, export, local, membind, nodeset, root, type, or width}

# # ## ### ##### ######## ############# #####################
## convert  --> /topology_convert.test
## cpubind  --> topology_cpubind.test
## cpuset   --> /topology_cpu_node_set.test (including 'element cpuset')
## destroy  --> /create.test
## membind  --> topology_membind.test
## nodeset  --> /topology_cpu_node_set.test (including 'element nodeset')

# # ## ### ##### ######## ############# #####################
## depth	/2
## export	/3
## local	/4
## element	/5
## element_by	/6
## root		/7
## type		/8
## width	/9

# - -- --- ----- -------- ------------- ---------------------
## depth ?type?

test hwloc-topology-2.0 {depth, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X depth Z Y
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X depth ?type?"}

# 2.1 dropped after syntax change

test hwloc-topology-2.2 {depth, overall} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X depth
} -cleanup {
    X destroy
} -result 2

test hwloc-topology-2.3 {depth, specific type} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X depth pu
} -cleanup {
    X destroy
} -result 1

test hwloc-topology-2.4 {depth, bogus type} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X depth bogus
} -cleanup {
    X destroy
} -returnCodes error \
    -result {bad element type "bogus": must be system, machine, numanode, socket, cache, core, pu, group, or misc}

test hwloc-topology-2.5 {depth, valid type, not in tree} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X depth cache
} -cleanup {
    X destroy
} -result -1

# - -- --- ----- -------- ------------- ---------------------
## export filename

test hwloc-topology-3.0 {export, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X export
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X export filename"}

test hwloc-topology-3.1 {export, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X export A B
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X export filename"}

test hwloc-topology-3.2 {export} -setup {
    hwloc create X -flags this_system -synthetic pu:4
    set path [tcltest::makeFile {} Z]
} -body {
    X export $path
    tcltest::viewFile Z
} -cleanup {
    X destroy
    tcltest::removeFile Z
    unset path
} -result [tcltest::viewFile pu4.xml $tcltest::testsDirectory]

# - -- --- ----- -------- ------------- ---------------------
## local

test hwloc-topology-4.0 {local, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X local Z
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X local"}

test hwloc-topology-4.1 {local, yes} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X local
} -cleanup {
    X destroy
} -result 1

test hwloc-topology-4.2 {local, no} -setup {
    hwloc create X -synthetic pu:4
} -body {
    X local
} -cleanup {
    X destroy
} -result 0

# - -- --- ----- -------- ------------- ---------------------
## depth ?-type type?

test hwloc-topology-5.0 {element, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X element args..."}

test hwloc-topology-5.1 {element, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element Z
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X element args..."}

test hwloc-topology-5.2 {element, bad id} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element Z foo
} -cleanup {
    X destroy
} -returnCodes error \
    -result {invalid element id}

test hwloc-topology-5.3 {element, bad id} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element \{ foo
} -cleanup {
    X destroy
} -returnCodes error \
    -result {invalid element id}

test hwloc-topology-5.4 {element, bad id} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element {x y} foo
} -cleanup {
    X destroy
} -returnCodes error \
    -result {expected integer but got "x"}

test hwloc-topology-5.5 {element, bad id} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element {0 y} foo
} -cleanup {
    X destroy
} -returnCodes error \
    -result {expected integer but got "y"}

test hwloc-topology-5.6 {element, out of range} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element {5 5} foo
} -cleanup {
    X destroy
} -returnCodes error \
    -result {element does not exist}

test hwloc-topology-5.6 {element, bad method} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element {0 0} foo
} -cleanup {
    X destroy
} -returnCodes error \
    -result {bad option "foo": must be arity, attributes, children, cpuset, depth, first_child, info, last_child, logical_index, name, next_cousin, next_sibling, nodeset, parent, prev_cousin, prev_sibling, sibling_rank, or type}

set k 0
foreach {method rc rr pc pr} {
    arity         ok    4                                 ok    0
    attributes    ok    Backend=Synthetic                 ok    {}
    children      ok    {{1 0} {1 1} {1 2} {1 3}}         ok    {}
    depth         ok    0                                 ok    1
    first_child   ok    {1 0}                             error {requested element does not exist}
    info          ok    {{Backend Synthetic}}             ok    {}
    last_child    ok    {1 3}                             error {requested element does not exist}
    logical_index ok    0                                 ok    2
    name          ok    {}                                ok    {}
    next_cousin   error {requested element does not exist} ok    {1 3}
    next_sibling  error {requested element does not exist} ok    {1 3}
    parent        error {requested element does not exist} ok    {0 0}
    prev_cousin   error {requested element does not exist} ok    {1 1}
    prev_sibling  error {requested element does not exist} ok    {1 1}
    sibling_rank  ok    0                                 ok    2
    type          ok    machine                           ok    pu
} {
    test hwloc-topology-5.7.$k "element, $method wrong\#args" -setup {
	hwloc create X -flags this_system -synthetic pu:4
    } -body {
	X element {0 0} $method Z
    } -cleanup {
	X destroy
    } -returnCodes error \
	-result "wrong # args: should be \"X element {0 0} $method\""

    test hwloc-topology-5.8.$k "element, $method, result, root" -setup {
	hwloc create X -flags this_system -synthetic pu:4
    } -body {
	X element {0 0} $method
    } -cleanup {
	X destroy
    } -returnCodes $rc -result $rr

    test hwloc-topology-5.9.$k "element, $method, result, leaf" -setup {
	hwloc create X -flags this_system -synthetic pu:4
    } -body {
	X element {1 2} $method
    } -cleanup {
	X destroy
    } -returnCodes $pc -result $pr

    incr k
}

# More detailed look at attributes and info, using a saved real topology.
set k 0
foreach {method obj result} {
    attributes {0 0} {local=775196KB total=775196KB Backend=Linux OSName=Linux OSRelease=2.6.7 OSVersion="#1 Wed September 08 20:12:03 EDT 2001" HostName=some-fake-box Architecture=i686}
    info       {0 0} {{Backend Linux} {OSName Linux} {OSRelease 2.6.7} {OSVersion {#1 Wed September 08 20:12:03 EDT 2001}} {HostName some-fake-box} {Architecture i686}}
    name       {0 0} {}
    attributes {1 0} {}
    info       {1 0} {}
    name       {1 0} {}
} {
    test hwloc-topology-5.10.$k "element, $method, result" -setup {
	hwloc create X -xml $tcltest::testsDirectory/topology1.xml
    } -body {
	X element $obj $method
    } -cleanup {
	X destroy
    } -result $result

    incr k
}

# - -- --- ----- -------- ------------- ---------------------
## element_by

test hwloc-topology-6.0 {element_by, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X element_by depth|type index"}

test hwloc-topology-6.1 {element_by, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by A
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X element_by depth|type index"}

# 6.2 dropped after syntax change

test hwloc-topology-6.3 {element_by, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by A B C
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X element_by depth|type index"}

# 6.4 dropped after syntax change
# 6.5 dropped after syntax change

test hwloc-topology-6.6 {element_by, bad level argument} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by B C
} -cleanup {
    X destroy
} -returnCodes error \
    -result {expected integer or element type but got "B"}

test hwloc-topology-6.7 {element_by, bad index} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by 0 C
} -cleanup {
    X destroy
} -returnCodes error \
    -result {expected integer but got "C"}

test hwloc-topology-6.8 {element_by, bad index} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by pu C
} -cleanup {
    X destroy
} -returnCodes error \
    -result {expected integer but got "C"}

test hwloc-topology-6.9 {element_by, bad depth, below min} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by -1 0
} -cleanup {
    X destroy
} -returnCodes error \
    -result {depth out of range}

test hwloc-topology-6.14 {element_by, bad depth, above max} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by 5 0
} -cleanup {
    X destroy
} -returnCodes error \
    -result {depth out of range}

test hwloc-topology-6.10 {element_by, out of range} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by 0 1
} -cleanup {
    X destroy
} -returnCodes error \
    -result {element does not exist}

test hwloc-topology-6.11 {element_by, unused type} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by cache 0
} -cleanup {
    X destroy
} -returnCodes error \
    -result {element does not exist}

test hwloc-topology-6.12 {element_by, by depth} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by 1 1
} -cleanup {
    X destroy
} -result {1 1}

test hwloc-topology-6.13 {element_by, by type} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X element_by pu 2
} -cleanup {
    X destroy
} -result {1 2}

# - -- --- ----- -------- ------------- ---------------------
## root

test hwloc-topology-7.0 {root, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X root Z
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X root"}

test hwloc-topology-7.1 {root} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X root
} -cleanup {
    X destroy
} -result {0 0}

# - -- --- ----- -------- ------------- ---------------------
## type n

test hwloc-topology-8.0 {type, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X type
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X type depth"}

# 8.1 dropped after syntax change.

test hwloc-topology-8.2 {type, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X type Z Y
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X type depth"}

test hwloc-topology-8.3 {type, bad depth, not integer} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X type Z
} -cleanup {
    X destroy
} -returnCodes error \
    -result {expected integer but got "Z"}

test hwloc-topology-8.4 {type, bad depth, below min} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X type -1
} -cleanup {
    X destroy
} -returnCodes error \
    -result {depth out of range}

test hwloc-topology-8.5 {type, bad depth, above max} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X type 2
} -cleanup {
    X destroy
} -returnCodes error \
    -result {depth out of range}

test hwloc-topology-8.6 {type} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X type 0
} -cleanup {
    X destroy
} -result machine

test hwloc-topology-8.7 {type} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X type 1
} -cleanup {
    X destroy
} -result pu

# - -- --- ----- -------- ------------- ---------------------
## width -depth n
## width -type type

test hwloc-topology-9.0 {width, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X width depth|type"}

test hwloc-topology-9.1 {width, wrong\#args} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width Z Y
} -cleanup {
    X destroy
} -returnCodes error \
    -result {wrong # args: should be "X width depth|type"}

# 9.2 dropped after syntax change

test hwloc-topology-9.3 {width, bad argument} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width foo
} -cleanup {
    X destroy
} -returnCodes error \
    -result {expected integer or element type but got "foo"}

test hwloc-topology-9.4 {width, bad depth} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width -1
} -cleanup {
    X destroy
} -returnCodes error \
    -result {depth out of range}

test hwloc-topology-9.5 {width, bad depth} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width 2
} -cleanup {
    X destroy
} -returnCodes error \
    -result {depth out of range}

# 9.6 dropped after syntax change

test hwloc-topology-9.7 {width, valid type, not in tree} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width cache
} -cleanup {
    X destroy
} -result 0

test hwloc-topology-9.8 {width, specific type} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width pu
} -cleanup {
    X destroy
} -result 4

test hwloc-topology-9.9 {width, specific depth} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width 0
} -cleanup {
    X destroy
} -result 1

test hwloc-topology-9.10 {width, specific depth} -setup {
    hwloc create X -flags this_system -synthetic pu:4
} -body {
    X width 1
} -cleanup {
    X destroy
} -result 4

# # ## ### ##### ######## ############# #####################
tcltest::cleanupTests
